/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.formserver.vmmanager.createvmmetadata;


import com.inspur.edp.bef.component.base.GspComponent;
import com.inspur.edp.formserver.viewmodel.util.ViewModelUtils;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataHeader;
import com.inspur.edp.lcm.metadata.api.entity.MetadataReference;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import java.util.ArrayList;

/**
 与元数据交互的工具
 
*/
public class GspMetadataExchangeUtil
{
	private final String VM_TYPE="VMComponent";
	private final String VM_FILESUFFIX=".vmCmp";
	private  final String VOACTIONCONTROLLER="VOActionController";
	 public static GspMetadataExchangeUtil getInstance(){
	 	return new GspMetadataExchangeUtil();
	 }
	private GspMetadataExchangeUtil()
	{
	}
	/** 
	 业务实体编号
	 
	*/
	private String privateVMActionCode;
	private String getVMActionCode()
	{
		return privateVMActionCode;
	}
	private void setVMActionCode(String value)
	{
		privateVMActionCode = value;
	}
	/** 
	 元数据存放路径
	 
	*/
	private String privateMetadataPath;
	private String getMetadataPath()
	{
		return privateMetadataPath;
	}
	private void setMetadataPath(String value)
	{
		privateMetadataPath = value;
	}
	/** 
	 元数据名称
	 
	*/
	private String privateComponentName;
	private String getComponentName()
	{
		return privateComponentName;
	}
	private void setComponentName(String value)
	{
		privateComponentName = value;
	}
	/** 
	 是否是新建元数据
	 
	*/
	private boolean privateIsNewMetadata;
	private boolean getIsNewMetadata()
	{
		return privateIsNewMetadata;
	}
	private void setIsNewMetadata(boolean value)
	{
		privateIsNewMetadata = value;
	}
	
	private String privateBizObjectID;
	private String getBizObjectID()
	{
		return privateBizObjectID;
	}
	private void setBizObjectID(String value)
	{
		privateBizObjectID = value;
	}
	
	private String privateNameSpace;
	private String getNameSpace()
	{
		return privateNameSpace;
	}
	private void setNameSpace(String value)
	{
		privateNameSpace = value;
	}
	/** 
	 创建构件元数据，返回构件元数据ID
	 
	 @param component 构件实体
	 @param path 生成构件元数据的路径
	 @param vmActionCode 业务实体编号
	 @return 
	 生成的构件元数据名称
	 <see cref="string"/>
	 
	*/
	public final String establishVMMetdadata(GspComponent component, String path, String vmActionCode, String bizObjectID, String nameSpace)
	{
		this.setIsNewMetadata(true);
		this.setVMActionCode(vmActionCode);
		this.setMetadataPath(path);
		this.setBizObjectID(bizObjectID);
		this.setNameSpace(nameSpace);
		//1、构建元数据实体
		GspMetadata metadata = buildGspMetadataEntity(component,false);
		//2、生成构件元数据
		return generateGspMetadata(metadata);
	}
	/** 
	 更新构件元数据
	 
	 @param component 构件实体
	 @param fullPath 要修改的构件元数据完整路径
	*/
	public final void updateGspMetadata(GspComponent component, String fullPath, String bizEntityCode, String bizObjectID, String nameSpace)
	{
		this.setIsNewMetadata(false);
		this.setVMActionCode(bizEntityCode);
		this.setBizObjectID(bizObjectID);
		this.setNameSpace(nameSpace);
		this.setMetadataPath(ViewModelUtils.getDirectoryName(fullPath));
		this.setComponentName(ViewModelUtils.getFileNameWithoutExtension(fullPath));
		//1、构建元数据实体
		GspMetadata metadata = buildGspMetadataEntity(component, true);
		updateComponentMetadata(metadata, fullPath);
	}


		///#region 构建构件元数据实体
	/** 
	 创建GspMetadata实体
	 
	 @param component 构件实体
	 @return GspMetadata实体
	*/

//ORIGINAL LINE: private GspMetadata buildGspMetadataEntity(GspComponent component, bool isUpdate=false)
	private GspMetadata buildGspMetadataEntity(GspComponent component, boolean isUpdate)
	{
		GspMetadata metadata = createMetadataEntity();

		evaluateMetadataHeader(component, metadata);
		evaluateMetadataContent(component, metadata);
		return metadata;
	}

	/** 
	 创建元数据实例
	 
	 @return 
	 实例化的元数据
	 <see cref="GspMetadata"/>
	 
	*/
	private GspMetadata createMetadataEntity()
	{
		GspMetadata tempVar = new GspMetadata();
		tempVar.setHeader(new MetadataHeader()); 
		tempVar.setRefs(new ArrayList<MetadataReference>());
		GspMetadata metadata = tempVar;
		return metadata;
	}
	/** 
	 为元数据的Header属性赋值
	 
	 @param component 构件实体
	 @param metadata 元数据实体
	*/
	private void evaluateMetadataHeader(GspComponent component, GspMetadata metadata)
	{
		if (ViewModelUtils.checkNull(metadata.getHeader().getNameSpace()))
		{
			metadata.getHeader().setNameSpace(getNameSpace());
		}

		metadata.getHeader().setName(generateComponentMetadataName(component, this.getMetadataPath()));
		metadata.getHeader().setCode (generateComponentMetadataName(component, this.getMetadataPath()));
		metadata.getHeader().setFileName(this.getComponentName() + VM_FILESUFFIX);
		metadata.getHeader().setType(VM_TYPE);

		if (!ViewModelUtils.checkNull(getBizObjectID()))
		{
			metadata.getHeader().setBizobjectID(getBizObjectID());
		}

		if (ViewModelUtils.checkNull(metadata.getHeader().getId()) && ViewModelUtils.checkNull(component.getComponentID())) //新建构件元数据时，需要初始化后获取ID
		{
			MetadataService metadataService = SpringBeanUtils.getBean(MetadataService.class);
			//初始化元数据，为了获取元数据ID
			metadata = metadataService.initializeMetadataEntity(metadata);
			component.setComponentID(metadata.getHeader().getId());
		}
		else if (ViewModelUtils.checkNull(metadata.getHeader().getId()) && !ViewModelUtils.checkNull(component.getComponentID())) //修改构件元数据时，需要为元数据的ID赋值
		{
			metadata.getHeader().setId(component.getComponentID());
		}
	}
	/** 
	 为元数据的Content属性赋值
	 
	 @param component 构件实体
	 @param metadata 元数据实体
	*/
	private void evaluateMetadataContent(GspComponent component, GspMetadata metadata)
	{
		metadata.setContent(component);
	}

		///#endregion

	/** 
	 生成构件元数据
	 
	 @param metadata 元数据
	 @param
	 @return 
	 生成的构件元数据名称
	 <see cref="string"/>
	 
	*/
	private String generateGspMetadata(GspMetadata metadata)
	{
		MetadataService metadataService = SpringBeanUtils.getBean(MetadataService.class);

		//创建元数据
		metadataService.createMetadata(this.getMetadataPath(), metadata);
		return metadata.getHeader().getCode();
	}

	private void updateComponentMetadata(GspMetadata metadata, String fullPath)
	{
		MetadataService metadataService = SpringBeanUtils.getBean(MetadataService.class);

		metadataService.saveMetadata(metadata, fullPath);
	}
	/** 
	 生成当前路径下唯一的元数据名称
	 
	 @param component 构件实体
	 @param path 生成的元数据存放路径
	 @return 唯一的要生成的元数据名称
	*/
	private String generateComponentMetadataName(GspComponent component, String path)
	{
		// 构件元数据命名规则
		String metadataFileName = this.getVMActionCode() + component.getComponentCode() + VOACTIONCONTROLLER;
		// 若为新增元数据操作，则需要检查路径下是否有重名元数据；若为修改元数据操作，则无需操作
		if (this.getIsNewMetadata())
		{
			String orgMetadataFileName = metadataFileName;
			String metadataFileNameWithSuffix = metadataFileName + VM_FILESUFFIX;
			int index = 0;
			MetadataService metadataService = SpringBeanUtils.getBean(MetadataService.class);
			while (metadataService.isMetadataExist(path, metadataFileNameWithSuffix))
			{
				//（同一个Be元数据中，若有重名，则自动增加后缀）
				metadataFileName = orgMetadataFileName + ++index;
				metadataFileNameWithSuffix = metadataFileName + VM_FILESUFFIX;
			}
			this.setComponentName(metadataFileName);
		}

		return metadataFileName;
	}
}
